iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
自我挑戰組

<< 測試魔法 >> 這能動嗎?不然就測測看好了!系列 第 7

React Testing Library 的一些好用選取方法

  • 分享至 

  • xImage
  •  

前情提要

「咦,艾草你昨天怎麼直接翹課不出沒了!」

「什麼翹課,偶爾也需要週休二日的好嗎(#`Д´)ノ」

「我怎麼覺得你好像變更黑了?」

「!!我昨天就跑去澎湖做個日光浴而已呀!」

「齁~~被我抓到翹課的原因了。」

「好啊,你居然拐我(#`Д´)ノ」艾草越想越不對勁,自己全身都毛(綠繡眼)怎麼會被看出變黑。

「ㄌㄩㄝ~不然你今天教我透過這兩把鏟子,我能怎麼選到防禦魔法陣的關鍵吧!」

「可以呀,突然很認真不錯唷 ~ 」

(我心中暗自想到:嘿嘿,把這招學起來不知道能不能把老是翹課的艾草找出來,還想偷懶呀!)
https://ithelp.ithome.com.tw/upload/images/20220922/20139066jYf0uqm1IK.png


今天來介紹一些 React Testing Library 的一些好用選取方法, React Testing Library 提供很多方法可以讓我們像使用者一樣選取網頁上的 DOM 元素,讓我們在測試時更切合實際。

首先讓我們來看 React Testing Library 提供的表格:

https://ithelp.ithome.com.tw/upload/images/20220922/20139066WtNelhhQpo.png

針對以上幾個方法來做個介紹:

getBy、getAllBy

getBy 在沒有比對到匹配及有多個匹配的情況下都會直接噴錯,且不適用於一開始並不會顯示的情況,例如某些元素是要在用戶有操作的情況下才會顯示的情形。

getAllBy 可以拿來選取多個匹配的元素,當有匹配到一個或多個時,會直接回傳一個陣列。

findBy、findAllBy

findBy 可以用來處理非同步,或是一開始不會顯示在頁面上,須執行對應動作重新渲染後才會顯示的畫面。

findAllBygetAllBy 一樣可以選取多個匹配的元素,適合用來選取非同步操作後顯示的元素。

queryBy、queryAllBy

適合用在比對是否沒有某個元素時,透過 queryBy 在沒有比對到元素的情況下並不會報錯,而是會回傳 null ,但也因為不會直接報錯,並不建議拿來選取存在的元素。

queryAllBy 在沒有匹配的情況下會回傳空陣列,一樣適合用在比對是否沒有某個元素。

queryBy 適合與 not 一起搭配使用:

expect(screen.queryByRole('button')).not.toBeInTheDocument();

不比對是否不存在某元素時,可以依情況使用 getByfindBy 即可。

接下來要介紹可以怎麼選取呢?有以下幾種方式:

  • ByText : 可以尋找 document 內符合的文字內容

要注意套件設定的 Role

  • ByRole

    可以透過標籤的角色去尋找想要的元素,角色可以透過此方式去觀看:

    • 叫出開發者工具後在 Elements 底下原先預設 Styles 的地方點擊最右側小箭頭 >> 圖示後選取 Accessibility 。
    • https://ithelp.ithome.com.tw/upload/images/20220922/20139066osvf5sMixs.png
    • 選取對應的 element 後底下會顯示 Role 角色!
    • https://ithelp.ithome.com.tw/upload/images/20220922/201390661zTt3eJ0qD.png
      以按鈕舉例可以這樣選取:
    screen.getByRole('button');
    

    如果有多顆按鈕的情況,可以在按鈕上添加 aria-label 屬性後透過 name 去指定:

    <button aria-label='first-button'>第一顆按鈕</button>
    
    // 透過 aria-label 指定名稱
    screen.debug(screen.getByRole('button', { name: /first-button/i }));
    

    這邊透過 Antd 的素材庫去舉例,也要特別提醒,如果是透過套件去渲染的元件,套件可能會有多個層級,此時要特別留意要做測試的層級,按照 Select 舉例該 input 可能包在很內層,input 內也有去設定 role 角色:
    https://ithelp.ithome.com.tw/upload/images/20220922/20139066sehY3Wu70x.png

  • ByLabelText : 尋找 label 屬性的文字內容。

  • ByPlaceholderText: 尋找 Placeholder 屬性的文字內容。

  • ByDisplayValue:尋找 value :如 input 、 select 等等的顯示值。

  • ByAltText:尋找 img 標籤的 Alt 屬性。

  • ByTitle:尋找有設定 title 屬性的元素。

  • ByTestId

    可以找出 data-testid 屬性,data-testid 要提前埋在標籤內:

    <div data-testid="test" />
    
    // 選取埋藏的 id 
    screen.getByTestId('test');
    

在選取時我們可能會需要先觀看目前頁面上可供選擇的元素,這時就可以使用底下幾個方法:

screen.debug()

screen.debug() 能幫我們印出現有的 DOM 元素,讓我們更方便去選取元素,也可以帶入參數,帶入參數後可單獨印出該元素。

// 會帶出所有目前頁面上的 dom 元素
screen.debug()
// 帶入參數選取想看的 dom 元素
screen.debug(screen.getByText('test'));

最後,官方文件也提到一個厲害的網站,可以幫助我們搜尋 DOM 元素:https://testing-playground.com/


小總結

針對今天的學習總結了幾點:

  • findBy... 可以選取非同步
  • queryBy... 可以與 not 搭配使用
  • ...AllBy... 可以選擇多個元素
  • 可透過 ByRole 選取 Elements 的 Role 後進行斷言
  • screen.debug() 可以打印出目前元件渲染出來的 DOM 元素

參考文獻

https://testing-library.com/docs/react-testing-library/cheatsheet/#queries
https://testing-playground.com/
https://testing-library.com/docs/queries/about/
https://ithelp.ithome.com.tw/articles/10281691
https://daily-dev-tips.com/posts/testing-library-awaiting-queries/
https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#using-query-variants-for-anything-except-checking-for-non-existence


上一篇
情境練習:函式測試
下一篇
Jest DOM 實用匹配器
系列文
<< 測試魔法 >> 這能動嗎?不然就測測看好了!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言